﻿using System.Collections.Generic;
using Pathfinding;
using UnityEngine;

namespace Helpers
{
    public static class NavHelper
    {
        private static int _obstacleLayer = -1;

        public static int ObstacleLayer
        {
            get
            {
                if (_obstacleLayer == -1)
                    _obstacleLayer = LayerMask.GetMask("Obstacles", "Wall", "BattleCharacter");
                return _obstacleLayer;
            }
        }

        #region Path
        public static bool SamplePosition(Vector3 pos, out Vector3 res)
        {
            return SamplePosition(pos, NNConstraint.Default, out res);
        }

        public static bool SampleNodePosition(Vector3 pos, out Vector3 nodePos)
        {
            nodePos = default;
            var res = SamplePosition(pos, NNConstraint.Default, out NNInfo info);
            if (!res) return false;
            nodePos = (Vector3) info.node.position;
            return true;
        }

        public static bool SamplePosition(Vector3 pos, NNConstraint constraint, out Vector3 res)
        {
            res = default;
            if (AstarPath.active == null) return false;
            var node = AstarPath.active.GetNearest(pos, constraint);
            if (node.node == null) return false;

            res = node.position;
            return true;
        }


        public static bool SamplePosition(Vector3 pos, NNConstraint constraint, out NNInfo res)
        {
            res = default;
            if (AstarPath.active == null) return false;
            res = AstarPath.active.GetNearest(pos, constraint);
            return res.node != null;
        }


        // public static ABPath SearchPath(Vector3 source, Vector3 destination)
        // {
        //     ABPath path = ABPath.Construct(source, destination);
        //     return path;
        // }

        /// <summary>
        /// 优化路径折点
        /// </summary>
        /// <param name="path"></param>
        public static void ZPathOptimize(List<Vector3> path)
        {
            // if (path.Count < 3) return;
            // // 高度修正，超过这个高度的物体将被视为障碍物
            // const float heightFix = .5f;
            // for (int i = path.Count - 1; i >= 2; i--)
            // {
            //     // Debug.Log(i + " " + path.Count);
            //     Vector3 p1 = path[i], p2 = path[i - 2];
            //     // 修正射线高度
            //     p1.y += heightFix;
            //     // 判断两点连线，如果中间没有障碍，则去掉中间点，连接这两点
            //     if (!Physics.Linecast(p1, p2, _obstacleLayer))
            //     {
            //         path.RemoveAt(i - 1);
            //     }
            // }
        }


        public static void BlockAt(Vector3 position, float radius) { }
        #endregion

        #region Node
        public static NNInfo GetNode()
        {
            // NNInfo info = null;
            
            return default;
        }
        #endregion
    }
}

public static class GridNodeExtend
{
    public static IEnumerable<GridNodeBase> GetNeighbours(this GridNodeBase self)
    {
        GridGraph gg = GridNode.GetGridGraph(self.GraphIndex);
        int[] neighbourOffsets = gg.neighbourOffsets;
        foreach (var offset in neighbourOffsets)
        {
            var neighbour = gg.nodes[self.NodeInGridIndex + offset];
            if (neighbour != null) yield return neighbour;
        }
    }


    // public static GridNodeBase GetNeighbourByDir(this GridNodeBase self, int x, int y)
    // {
    //     GridGraph gg = GridNode.GetGridGraph(self.GraphIndex);
    //     int index = self.NodeInGridIndex 
    //     return null;
    // }    
}